
#include <malloc.h>

#include "envio-vector.h"
#include "../nodo/nodo.h"
#include "../varios/compresion.h"
#include "../varios/log.h"
#include "../varios/mensajes.h"
#include "../varios/mpi-utiles.h"
#include "../../compartido/vectores.h"


/*
 * Implementacion de funcion definida en cabecera
 */
void enviarVector(int cantNodos, struct VECTOR *vector, struct ASIGNACION_NODO **asignaciones) {

    LOGGER("Enviamos el vector a los nodos de trabajo");
    
    // Creamos el buffer para lectura del vector
    int *bufferLectura = malloc(MAX_CANT_ELEM*sizeof(int));
    
    long long offsetVector = 0; // Indice de lectura del vector completo
    
    int p; // Hacemos envios por nodo completo
    for (p=cantNodos-1; p>=0; p--) {

        long long offsetVectorNodo = 0;
        long long tamVectorNodo = asignaciones[p]->tamVectorInicial;
        
        LOGGER("Comenzamos el envío del vector al nodo %d, desde el offset %l", p+1, offsetVector);
        
        while(offsetVectorNodo<tamVectorNodo) {
            
            LOGGER("Offset del vector al nodo al inicio de ciclo %l", offsetVectorNodo);
            
            long long cantRestanteNodo = tamVectorNodo-offsetVectorNodo;
            
            int leerCantidad;
            if (cantRestanteNodo >= MAX_CANT_ELEM) {
                leerCantidad = MAX_CANT_ELEM;
            } else {
                leerCantidad = cantRestanteNodo;
            }
            
            LOGGER("Debemos enviar %d elementos de un total de %l", leerCantidad, tamVectorNodo);

            long long u;
            for (u=0; u<leerCantidad; u++) {
                bufferLectura[u] = obtenerValor(vector, offsetVector + offsetVectorNodo + u);
            }
            
            // Comprimimos los datos leidos
            char *datosComprimir = (char *)bufferLectura;
            int tamDatos = sizeof(int) * leerCantidad;
            struct DATOS_COMPRIMIDOS comp = comprimir(datosComprimir, tamDatos);
            
            // Enviamos los datos comprimidos
            LOGGER("Enviamos los datos datos comprimidos");
            enviarDatos(p+1, MSG_VECTOR_INICIAL, comp.datosCompr, comp.longitudCompr);
            
            free(comp.datosCompr);
             
            offsetVectorNodo += leerCantidad;
        
        }
        
        offsetVector += tamVectorNodo;
        
    }
    
    // Liberamos memoria
    free(bufferLectura);
    
    LOGGER("Finaliza envio del vector a los nodos");
    
}
